﻿using MongoDB.Driver;
using Sustainalytics.Entities.RiskRatings;
using Sustainalytics.Utils;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace Sustainalytics.RiskRatings.Service.Controllers
{
    [RoutePrefix("api/v1/clusters")]
    [LogControllerFilter(true, true, false)]
    public class ClustersController : ApiController
    {
        private readonly IMongoCollection<RiskRatingCluster> _riskRatingClusterCollection;
        private readonly IMongoCollection<ManagementCluster> _managementClusterCollection;
        private readonly IMongoCollection<ManageableCluster> _manageableClusterCollection;
        private readonly IMongoCollection<ExposureCluster> _exposureClusterCollection;

        public ClustersController(
            IMongoCollection<RiskRatingCluster> riskRatingClusterCollection,
            IMongoCollection<ManagementCluster> managementClusterCollection,
            IMongoCollection<ManageableCluster> manageableClusterCollection,
            IMongoCollection<ExposureCluster> exposureClusterCollection
            )
        {
            _riskRatingClusterCollection = riskRatingClusterCollection;
            _managementClusterCollection = managementClusterCollection;
            _manageableClusterCollection = manageableClusterCollection;
            _exposureClusterCollection = exposureClusterCollection;
        }

        [HttpGet]
        [Route("company")]
        public async Task<HttpResponseMessage> GetCompanyRiskClusters()
        {
            var riskClusters = await _riskRatingClusterCollection.Find(x => x.Type == RiskRatingClusterType.Overall).SortBy(x => x.LowerBound).ToListAsync().ConfigureAwait(false);

            if (riskClusters == null)
                return Request.CreateResponse(HttpStatusCode.NotFound);

            return Request.CreateResponse(HttpStatusCode.OK, riskClusters.Select(x => new {
                x.Id,
                x.LowerBound,
                x.UpperBound,
                x.Code,
                x.Assessment,
                Name = x.Assessment.ToString()
            }));
        }

        [HttpGet]
        [Route("management/{clusterType}")]
        public async Task<HttpResponseMessage> GetCompanyManagementClusters([FromUri]RiskRatingClusterType clusterType = RiskRatingClusterType.Overall)
        {
            var managementClusters = await _managementClusterCollection.Find(x => x.Type == clusterType).SortBy(x => x.LowerBound).ToListAsync().ConfigureAwait(false);

            if (managementClusters == null)
                return Request.CreateResponse(HttpStatusCode.NotFound);

            return Request.CreateResponse(HttpStatusCode.OK, managementClusters.Select(x => new {
                x.Id,
                x.LowerBound,
                x.UpperBound,
                x.Assessment,
                Name = x.Assessment.ToString()
            }));
        }

        [HttpGet]
        [Route("manageable/{clusterType}")]
        public async Task<HttpResponseMessage> GetCompanyManageableClusters([FromUri]RiskRatingClusterType clusterType = RiskRatingClusterType.Overall)
        {
            var manageableClusters = await _manageableClusterCollection.Find(x => x.Type == clusterType).SortBy(x => x.LowerBound).ToListAsync().ConfigureAwait(false);

            if (manageableClusters == null)
                return Request.CreateResponse(HttpStatusCode.NotFound);

            return Request.CreateResponse(HttpStatusCode.OK, manageableClusters.Select(x => new {
                x.Id,
                x.LowerBound,
                x.UpperBound,
                x.Assessment,
                Name = x.Assessment.ToString()
            }));
        }

        [HttpGet]
        [Route("exposure/{clusterType}")]
        public async Task<HttpResponseMessage> GetCompanyExposureClusters([FromUri]RiskRatingClusterType clusterType = RiskRatingClusterType.Overall)
        {
            var exposureClusters = await _exposureClusterCollection.Find(x => x.Type == clusterType).SortBy(x => x.LowerBound).ToListAsync().ConfigureAwait(false);

            if (exposureClusters == null)
                return Request.CreateResponse(HttpStatusCode.NotFound);

            return Request.CreateResponse(HttpStatusCode.OK, exposureClusters.Select(x => new {
                x.Id,
                x.LowerBound,
                x.UpperBound,
                x.Assessment,
                Name = x.Assessment.ToString()
            }));
        }

        [HttpGet]
        [Route("mei")]
        public async Task<HttpResponseMessage> GetMeiRiskClusters()
        {
            var riskClusters = await _riskRatingClusterCollection.Find(x => x.Type == RiskRatingClusterType.MEI).SortBy(x => x.LowerBound).ToListAsync().ConfigureAwait(false);

            if (riskClusters == null)
                return Request.CreateResponse(HttpStatusCode.NotFound);

            return Request.CreateResponse(HttpStatusCode.OK, riskClusters.Select(x => new {
                x.Id,
                x.LowerBound,
                x.UpperBound,
                x.Code,
                x.Assessment,
                Name = x.Assessment.ToString()
            }));
        }
    }
}